梦入琼楼寒有月,行过石树冻无烟

Vue.js form at v-model

vue 的表单处理主要通过v-model指令,且仅仅限制于在<input>、<select>、<textarea>等HTML表单元素创建双向数据绑定。v-model可以根据HTML控件的类型来自动选取正确的方法来进行更新。

当使用输入法如中日韩等语言时,需要使用 value 绑定,而不是 v-model

需要值得注意的是v-model指令会忽略所有的表单value、checked、selected等属性的初始值,所以需在js内的data选项中声明初始值。

指令在内部为不同的输入元素使用了不同的属性并抛出不同的事件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

| Name | Info |
| ---------------- | ---------------------------------- |
| text & textarea | 使用value 属性和input 事件 |
| checkbox & radio | 使用 checked 属性 和 change 事件 |
| select | 将以value 作为属性并和 change 事件 |


## Demo
### input
![](https://49812933408852955071488026628034-1301075051.cos.ap-nanjing.myqcloud.com/javascript/vue/vue%203.0/9.vue.js%20form%20at%20v-model.md/2277112239194.png)
当使用 ```v-model``` 绑定 message 属性的时候,通过 Mustache 表达式获取 message 属性值来达到双向绑定的效果。

> 在 ```<input>``` 元素中所设置的 value 默认值将不会被绑定,这是因为 ```v-model``` 指令会忽略所有表单元素的 value、checked、selected 属性的初始值,更或者说该指令只会获取 ```v-model``` 所绑定的 message 属性值。


```js
<ui id="app">
<input type="text" v-model="message" placeholder="echo" />
<p>{{message}}</p>
</ui>
<script>
const app = Vue.createApp ({
data() {
return {
message: null
}
},
methods: {
echo(message, event) {
alert(message)
if (event) {
alert('v-on:' + event.target.tagName)
}
}
}
})
const vm = app.mount('#app')
</script>

checkbox

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<ui id="app">
<input type="checkbox" v-model="message" />
<label>This is message: {{message}}</label>
</ui>
<script>
const app = Vue.createApp ({
data() {
return {
message: false
}
},
methods: {
echo(message, event) {
alert(message)
if (event) {
alert('v-on:' + event.target.tagName)
}
}
}
})
const vm = app.mount('#app')
</script>
复选框 value 绑定

直接通过 checkbox 的 value 来写入 message 数组当中,当显示的时候也是以数组的形式进行处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<ui id="app">
<h2>JavaScript</h2>
<input type="checkbox" v-model="message" value="Vue" /><label>Vue</label>
<input type="checkbox" v-model="message" value="Jquery" /><label>Jquery</label>
<input type="checkbox" v-model="message" value="Ajax" /><label>Ajax</label>
<input type="checkbox" v-model="message" value="D3.js" /><label>D3.js</label>
<input type="checkbox" v-model="message" value="Lodash" /><label>Lodash</label>
<h2>Web</h2>
<input type="checkbox" v-model="message" value="Node.js"><label>Node.js</label>
<input type="checkbox" v-model="message" value="Java"><label>Java</label>
<input type="checkbox" v-model="message" value="PHP"><label>PHP</label>
<input type="checkbox" v-model="message" value="GO"><label>GO</label>
<h2>SQL</h2>
<input type="checkbox" v-model="message" value="MySQL"><label>MySQL</label>
<input type="checkbox" v-model="message" value="Redis"><label>Redis</label>
<input type="checkbox" v-model="message" value="SQL"><label>SQL</label>
<input type="checkbox" v-model="message" value="HBase"><label>HBase</label>
<input type="checkbox" v-model="message" value="ORACLE"><label>ORACLE</label>
<hr />
<p>This is message: {{message}}</p>
</ui>
<script>
const app = Vue.createApp ({
data() {
return {
message: []
}
},
methods: {
echo(message, event) {
alert(message)
if (event) {
alert('v-on:' + event.target.tagName)
}
}
}
})
const vm = app.mount('#app')
</script>

radio


对于 radio 类型的 <input> 元素依然可以使用 value 对 message 进行双向的数据绑定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<ui id="app">
<h2>JavaScript</h2>
<input type="radio" v-model="message" value="Vue" /><label>Vue</label>
<input type="radio" v-model="message" value="Jquery" /><label>Jquery</label>
<input type="radio" v-model="message" value="Ajax" /><label>Ajax</label>
<input type="radio" v-model="message" value="D3.js" /><label>D3.js</label>
<input type="radio" v-model="message" value="Lodash" /><label>Lodash</label>
<h2>Web</h2>
<input type="radio" v-model="message" value="Node.js"><label>Node.js</label>
<input type="radio" v-model="message" value="Java"><label>Java</label>
<input type="radio" v-model="message" value="PHP"><label>PHP</label>
<input type="radio" v-model="message" value="GO"><label>GO</label>
<h2>SQL</h2>
<input type="radio" v-model="message" value="MySQL"><label>MySQL</label>
<input type="radio" v-model="message" value="Redis"><label>Redis</label>
<input type="radio" v-model="message" value="SQL"><label>SQL</label>
<input type="radio" v-model="message" value="HBase"><label>HBase</label>
<input type="radio" v-model="message" value="ORACLE"><label>ORACLE</label>
<hr />
<p>This is message: {{message}}</p>
</ui>
<script>
const app = Vue.createApp ({
data() {
return {
message: []
}
},
methods: {
echo(message, event) {
alert(message)
if (event) {
alert('v-on:' + event.target.tagName)
}
}
}
})
const vm = app.mount('#app')
</script>

textarea

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<ui id="app">
<textarea v-model="message" placeholder="echo"></textarea>
<p>This is message: {{message}}</p>
<hr />
<p style="white-space: pre-line">This is message: {{message}}</p>
</ui>
<script>
const app = Vue.createApp ({
data() {
return {
message: null
}
},
methods: {
echo(message, event) {
alert(message)
if (event) {
alert('v-on:' + event.target.tagName)
}
}
}
})
const vm = app.mount('#app')
</script>
元素通常用于处理较多的文字输入,因此对他双向绑定可以使用 [white-space](https://developer.mozilla.org/zh-CN/docs/Web/CSS/white-space) 来处理用户的换行输入。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

### select
![](https://49812933408852955071488026628034-1301075051.cos.ap-nanjing.myqcloud.com/javascript/vue/vue%203.0/9.vue.js%20form%20at%20v-model.md/1237909103084.png)

```js
<ui id="app">
<select v-model="message">
<option disabled value="">Select</option>
<option value="vue">Vue</option>
<option value="Jqery">Jquery</option>
</select>
<hr />
<p>This is message: {{message}}</p>
</ui>
<script>
const app = Vue.createApp ({
data() {
return {
message: ''
}
},
methods: {
echo(message, event) {
alert(message)
if (event) {
alert('v-on:' + event.target.tagName)
}
}
}
})
const vm = app.mount('#app')
</script>

在上述的code当中,我们主要通过使用 value 来设置 option 被选择时的属性,此时 value 依然会写入 message,之后 <p> 元素对 message 进行数据绑定。

修饰符

在 vue中,自然而然的也为表单处理所加入了一些较为常用的修饰符,如.lazy、.number、.trim,他们分别对输入和输出进行提供了修改:

Name Info
.lazy 当输入完成时在同步信息
.number 将输入的值自动转换为 number类型
.trim 自动过滤首尾空白

.lazy

在未使用 .lazy 的情况下,<input> 所接受到触点事件将会记录我们所写入的信息,自然而然的也会传入到 message 属性中,而 .lazy 的主要作用就是当 <input> 触点事件结束时才开始将数据发送给 message

.trim

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

```js
<ui id="app">
<textarea v-model.trim="message" placeholder="start"></textarea>
<textarea v-model="trims" placeholder="start"></textarea>
<hr />
<p>This is message: {{message}}</p>
<p>This is message: {{trims}}</p>
</ui>
<script>
const app = Vue.createApp ({
data() {
return {
message: '',
trims: ''
}
},
methods: {
echo(message, event) {
alert(message)
if (event) {
alert('v-on:' + event.target.tagName)
}
}
}
})
const vm = app.mount('#app')
</script>

.number

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

> 但需要输入头部数据是 number 类型,否则 ```.number``` 修饰符的作用不大

```js
<ui id="app">
<textarea v-model.number="message" placeholder="echo"></textarea>
<hr />
<p>This is message: {{message}}</p>
</ui>
<script>
const app = Vue.createApp ({
data() {
return {
message: ''
}
},
methods: {
echo(message, event) {
alert(message)
if (event) {
alert('v-on:' + event.target.tagName)
}
}
}
})
const vm = app.mount('#app')
</script>
⬅️ Go back